package api

import (
	"encoding/json"
	"errors"
	//"time"

	"github.com/wuhuang26/locstor"
	"web/xhr"
)

var globalToken string

//var sendCount int

func send(method, url string, data []byte) ([]byte, error) {
	// 如果需要调试对话框等待、错误提示效果，请去除注释
	//if method == "POST" || method == "PUT" {
	//	time.Sleep(1 * time.Second)
	//	sendCount++
	//	if sendCount%3 != 0 {
	//		return nil, errors.New("hack error msg")
	//	}
	//}
	req := xhr.NewRequest(method, "/api/"+url)
	req.SetRequestHeader("Content-Type", "application/json")
	if globalToken != "" {
		req.SetRequestHeader("Authorization", "Bearer "+globalToken)
	}
	req.SetResponseType(xhr.ArrayBuffer)
	err := req.SendBytes(data)
	if err != nil {
		return nil, err
	}
	respData := req.GetResponseBytes()
	if req.GetStatus() >= 400 {
		var respErr Error
		jErr := json.Unmarshal(respData, &respErr)
		if jErr != nil {
			println("failed to unmarshal:", jErr)
		} else if respErr.Message != "" || respErr.Type != "" {
			return nil, &respErr
		}
		return nil, errors.New(req.GetStatusText())
	}
	return respData, nil
}

type Error struct {
	Message string `json:"message"`
	Type    string
	Arg     json.RawMessage
}

func (err *Error) Error() string {
	return err.Message
}

type AuthInfo struct {
	Username string
	Password string
}

func Login(info *AuthInfo) error {
	globalToken = ""
	data, err := json.Marshal(info)
	if err != nil {
		return err
	}
	respData, err := send("POST", "login", data)
	if err != nil {
		return err
	}
	var t struct {
		Token string
	}
	err = json.Unmarshal(respData, &t)
	if err != nil {
		return err
	}

	globalToken = t.Token
	err = locstor.SetItem("token", globalToken)
	if err != nil {
		return err
	}
	return nil
}

type UserInfo struct {
	Name string
}

func CheckLogin() (string, error) {
	token, err := locstor.GetItem("token")
	if err == nil && token != "" {
		globalToken = token
		data, err := send("GET", "user", nil)
		if err != nil {
			globalToken = ""
			return "", err
		}
		var userInfo UserInfo
		err = json.Unmarshal(data, &userInfo)
		if err != nil {
			globalToken = ""
			return "", err
		}

		return userInfo.Name, nil
	}
	return "", errors.New("not found token")
}

func Logout() error {
	globalToken = ""
	return locstor.RemoveItem("token")
}
